/**
 * @fileoverview
 * This script defines utilities for interacting with data from www.fly-ted.org.
 * @author <a href="http://purl.org/net/aliman">Alistair Miles</a>, Graham Klyne, Jun Zhao
 * @version $Revision:538 $ on $Date: 2008-08-27 09:08:41 +0100 (Wed, 27 Aug 2008) $ by $Author: aliman $
 * @requires YAHOO.util.Connect
 * @requires flyui.bdgp.GeneNameMappings
 * TODO license terms
 */

// create a namespace if not already defined
flyui.namespace("flyui.bdgp");

/**
 * TODO doc me
 */
flyui.bdgp.Service = function (endpointURL) {
	/**
	 * @private
	 */
	this._endpoint = endpointURL;
}


// extend
flyui.bdgp.Service.prototype = new flyui.sparql.Service();


flyui.bdgp.Service.prototype.findImagesByAnyGeneLabel = function( geneLabel, success, failure) {
    var _context = "flyui.bdgp.Service.prototype.findImagesByAnyGeneLabel";
	try {
		flyui.info("geneLabel: "+geneLabel, _context);
		var successChain = flyui.chain(flyui.bdgp.Service.responseToImages, success);
		var query = flyui.bdgp.Service._buildQueryForFindImagesByAnyGeneLabel(geneLabel);		
		this.query(query, successChain, failure);
	} catch (error) {
        	throw new flyui.UnexpectedException(_context, error);
    }	
}


/**
 * Convert an HTTP response to an array of Images.
 * @param {Object} response a YUI success case response object
 * @type Array<flyui.bdgp.Image>
 * @static
 */
flyui.bdgp.Service.responseToImages = function( response ) {
    var _context = "flyui.bdgp.Service.responseToImages";
    try {
        flyui.debug("response status: "+response.status, _context);
        flyui.debug("response text: "+response.responseText, _context);
        flyui.debug("try parsing response text as json", _context);
        var resultSet = YAHOO.lang.JSON.parse(response.responseText);
        flyui.debug("convert result set to an array of genes", _context);
        var images = flyui.bdgp.Stage.newInstancesFromSPARQLResults(resultSet);
        return images;        
    } catch (e) {
        flyui.debug("caught "+e.name+", "+e.message, _context);
        throw new flyui.UnexpectedException(_context, e);
    }
}


/**
 * Build a SPARQL query to retrieve images by bdgp gene name.
 * @param {String} anyName the gene name to search by
 * @return a SPARQL query
 * @type String
 * @private
 * @static
 */
flyui.bdgp.Service._buildQueryForFindImagesByAnyGeneLabel = function( geneLabel ) {

	try {
		var prefixes = 	"PREFIX bdgp: <http://purl.org/net/bdgp/schema/>  " +
						"PREFIX owl: <http://www.w3.org/2002/07/owl#> " +
						"PREFIX skos: <http://www.w3.org/2004/02/skos/core#> " +
						"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> " +
						"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> " +		
						"PREFIX : <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#> " +
						"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
						"PREFIX dc: <http://purl.org/dc/elements/1.1/> ";					
	
	    var body = "select distinct ?imagepath ?stage ?developmentStage ?expression where {" +
	              "?gp skos:altLabel '" + geneLabel + "'; rdf:type bdgp:GeneProduct ." +
	              "?association bdgp:geneProduct ?gp ; bdgp:associate ?evidence ; bdgp:term ?term." +
	              "?evidence bdgp:evidence ?img ." +
	              "?img rdf:type bdgp:Image ; bdgp:imagePath ?imagepath." +
	              "?img bdgp:imageToTerm ?stage." +
	              "?stage bdgp:name ?developmentStage." +
	              "?term bdgp:name ?expression ." +
	              "}" + 
	              "order by ?stage";
	              
							
		var query = prefixes + body;
	
		return query;
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.Service._buildQueryForFindImagesByAnyGeneLabel", error);
    }
};

flyui.bdgp.Stage = function (){
	try {
		var that = this;
		
		this.stageName = null;
		
		this.images = new Array();
		
		this.stageURI = null;
		
		this.addImage = function (image){
			flyui.util.appendIfNotMember(that.images, image);
		};
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.Stage", error);
    }
};

/**
 * TODO doc me
 */
flyui.bdgp.Stage.newInstancesFromSPARQLResults = function( resultSet ) {
	try {
	
		var stagePool = new flyui.bdgp.StagePool();
		var imagePool = new flyui.bdgp.ImagePool();
		var bindings = resultSet.results.bindings;
		
		for (var i=0; i<bindings.length; i++) {
			var binding = bindings[i];
			var stageURI = binding.stage.value;
			var stage = stagePool.get (stageURI);	
					
			if (binding.developmentStage && !stage.stageName) {
				stage.stageName = binding.developmentStage.value;
			}
			
			if (binding.imagepath){
				var imageURI = binding.imagepath.value;
				var image = imagePool.get(imageURI);
				
				if (!image.expressions){
					image.expressions = new Array();
				}
	
				if (binding.expression) {
					var expression = binding.expression.value;
					if (expression == "stage1-3" || expression == "stage4-6" || expression == "stage7-8" || expression == "stage9-10" || expression == "stage11-12" || expression == "stage13-16"){
						flyui.debug("test: " + expression + " is not an expression term" );
					}else{
						flyui.util.appendIfNotMember(image.expressions, expression);
					}
				}
				stage.addImage(image);
			}		
		}
		return stagePool.toArray();
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.Stage.newInstancesFromSPARQLResults", error);
    }
};

/**
 * Create a pool of image objects.
 * @class
 * A pool of image objects.
 * @constructor
 */
 
flyui.bdgp.ImagePool = function() {
	/**
	 * @private
	 */
	this._pool = new Object();
};

flyui.bdgp.StagePool = function() {
	this._pool = new Array();
}

flyui.bdgp.StagePool.prototype.get = function( stageURI ) {
	try {
		var stage = this._pool[stageURI];
		
		if ( typeof stage == "undefined" || !stage ) {
			stage = new flyui.bdgp.Stage();
			stage.stageURI = stageURI;
			this._pool[stageURI] = stage;	
		}
		
		return stage;
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.StagePool.prototype.get", error);
    }
};

flyui.bdgp.StagePool.prototype.toArray = function() {
	try {
		var array = new Array();	
		for (var key in this._pool) {
			array[array.length] = this._pool[key];
		}
		return array;
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.StagePool.prototype.toArray", error);
    }
}

/**
 * Get a image object from the pool, or create a new one if it doesn't exist.
 * @param {String} imagepath 
 * @return a flyui.bdgp.Image object
 */
flyui.bdgp.ImagePool.prototype.get = function( imagepath ) {
	try {
		var image = this._pool[imagepath];
		
		if (!image ) {
			image = new Object();
			image.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/" + imagepath;
			image.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/" + imagepath;
			this._pool[imagepath] = image;	
		}
		
		return image;
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.ImagePool.prototype.get", error);
    }
};

flyui.bdgp.ImagePool.prototype.toArray = function() {
	try {
		var array = new Array();
		for (var key in this._pool) {
			array[array.length] = this._pool[key];
		}
		return array;
	}catch (error) {
        	throw new flyui.UnexpectedException("flyui.bdgp.ImagePool.prototype.toArray", error);
    }
}

